#include "driver_oled.h"
#include "driver_i2c.h"
#include "font.h"


void OLED_Write_Cmd(uint8_t cmd)
{
    I2C_Start();
    I2C_WriteByte(0X78);
    I2C_GetAck_From_Slave();
    I2C_WriteByte(0x00);
    I2C_GetAck_From_Slave();
    I2C_WriteByte(cmd);
    I2C_GetAck_From_Slave();
    I2C_Stop();
}


void OLED_Write_Data(uint8_t data)
{
    I2C_Start();
    I2C_WriteByte(0X78);
    I2C_GetAck_From_Slave();
    I2C_WriteByte(0x40);
    I2C_GetAck_From_Slave();
    I2C_WriteByte(data);
    I2C_GetAck_From_Slave();
    I2C_Stop();
}


void OLED_WriteNBytes(uint8_t *buf, uint16_t length)
{
    uint16_t i = 0;
    if(buf == NULL) return;
    I2C_Start();
    I2C_WriteByte(0X78);
    I2C_GetAck_From_Slave();
    I2C_WriteByte(0x40);
    I2C_GetAck_From_Slave();
    for(i=0; i<length; i++)
    {
        I2C_WriteByte(buf[i]);
        I2C_GetAck_From_Slave();
    }
    I2C_Stop();
}


void OLED_Init(void)
{
//    OLED_Write_Cmd(0xAE);    //设置显示开启/关闭，0xAE关闭，0xAF开启

//    OLED_Write_Cmd(0xD5);    //设置显示时钟分频比/振荡器频率
//    OLED_Write_Cmd(0x80);    //0x00~0xFF
    HAL_Delay(1);
    OLED_Write_Cmd(0xA8);    //设置多路复用率
    OLED_Write_Cmd(0x3F);    //0x0E~0x3F

    OLED_Write_Cmd(0xD3);    //设置显示偏移
    OLED_Write_Cmd(0x00);    //0x00~0x7F

    OLED_Write_Cmd(0x40);    //设置显示开始行，0x40~0x7F

    OLED_Write_Cmd(0xA1);    //设置左右方向，0xA1正常，0xA0左右反置

    OLED_Write_Cmd(0xC8);    //设置上下方向，0xC8正常，0xC0上下反置

    OLED_Write_Cmd(0xDA);    //设置COM引脚硬件配置
    OLED_Write_Cmd(0x12);

    OLED_Write_Cmd(0x81);    //设置对比度
    OLED_Write_Cmd(0xCF);    //0x00~0xFF

//    OLED_Write_Cmd(0xD9);    //设置预充电周期
//    OLED_Write_Cmd(0xF1);

//    OLED_Write_Cmd(0xDB);    //设置VCOMH取消选择级别
//    OLED_Write_Cmd(0x30);

    OLED_Write_Cmd(0xA4);    //设置整个显示打开/关闭

    OLED_Write_Cmd(0xA6);    //设置正常/反色显示，0xA6正常，0xA7反色

    OLED_Write_Cmd(0x8D);    //设置充电泵
    OLED_Write_Cmd(0x14);

    OLED_Write_Cmd(0xAF);    //开启显示 
}


void OLED_SetPosition(uint8_t page, uint8_t col)
{
    OLED_Write_Cmd(0xB0+page);
    OLED_Write_Cmd((col & 0x0F) | 0x00);
    OLED_Write_Cmd(((col & 0xF0) >> 4) | 0x10);
}


void OLED_Clear(void)
{
    uint8_t i = 0;
    uint8_t buf[128] = {0};
    
    for(i=0; i<8; i++)
    {
        OLED_SetPosition(i, 0);
        OLED_WriteNBytes(buf, 128);
    }
}


void OLED_DBClear(int page)
{
    uint8_t i = page;
    uint8_t buf[128] = {0};
    
    for(; i<page+2; i++)
    {
        OLED_SetPosition(i, 0);
        OLED_WriteNBytes(buf, 128);
    }
}


void OLED_PutChar(uint8_t page, uint8_t col, char c)
{
    OLED_SetPosition(page, col);
    OLED_WriteNBytes((uint8_t*)&ascii_font[c][0], 8);
    
    OLED_SetPosition(page + 1, col);
    OLED_WriteNBytes((uint8_t*)&ascii_font[c][8], 8);
}


void OLED_PrintString(uint8_t page, uint8_t col, char *str)
{
    while(*str != '\0')
    {
        OLED_PutChar(page, col, *str);
        col += 8;
        if(col > 127)
        {
            page += 2;
        }
        
        if(page > 7)
        {
            page = 0;
        }        
        str++;
    }
    HAL_Delay(10);
}

